#pragma once

#include <boost/noncopyable.hpp>
#include <string>
#include <memory>

#include <ISignal.hpp>
#include <IAcceptor.hpp>

class IIOServicePool;
class IConnection;
class IConnectionFactory;

class Server : private boost::noncopyable, public ISignalHandler, public IAcceptorHandler
{
public:
	/// Construct the server to listen on the specified TCP address and port, and
	/// serve up files from the given directory.
	Server(const std::string& address, const std::string& port, IIOServicePool& ioServicePool,
		ISignal& signal, IAcceptor& acceptor, IConnectionFactory& connectionFactory);
	virtual ~Server();

	/// Run the server's io_service loop.
	void run();

private:
	/// Initiate an asynchronous accept operation.
	void startAccept();

	/// Handle completion of an asynchronous accept operation.
	virtual void onAccepted(const boost::system::error_code&) override;

	/// Handle a request to stop the server.
	virtual void handleSignal() override;

	
	IConnectionFactory& m_connectionFactory;

	/// The pool of io_service objects used to perform asynchronous operations.
	IIOServicePool& m_ioServicePool;

	/// The signal_set is used to register for process termination notifications.
	ISignal& m_signals;

	/// Acceptor used to listen for incoming connections.
	IAcceptor& m_acceptor;

	/// The next connection to be accepted.
	std::shared_ptr<IConnection> m_newConnection;
};
